<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  <title>Document</title>
  <style>
    * {
      font-family: arial,sans-serif;
    }
    ul, li{
      list-style-type: none;
      padding: 0;
      margin:0;
    }
    .filestate {
      width: 100%;
      display:inline-block;
      height: 1em;
      border: 1px solid #AAA;
      background: #eee;
    }
    .front {
      background-color: steelblue;
      display: inline-block;
      height: 1em;
    }
    .filestate-disable {
      background-color: red;
    }
    table {
      border-collapse: collapse;
    }
    td,th{
      border: 1px solid #AAA;
      padding: 0.3em 1.5em;
    }
  </style>
</head>
<body>
  <form action="/upload" method="POST" enctype="multipart/form-data">
    <h1>SWM</h1>
    <label>上传文件：<input id="file" type="file" name="zipfile" onchange="fileChange()"/></label>
    <ul id="uploading-state">
      <li>
        <span class="filename"></span>
      </li>
      <li><span class="filesize"></span></li>
    </ul>
    <span class="filestate"><span class="front"></span></span>
    <hr />
    <table id="files">
      <thead>
        <tr>
          <th>文件名</th>
          <th>上传日期</th>
          <th>目录文件夹</th>
          <th>文件尺寸</th>
          <th>端口</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
    {{files}}
  </form>
  <script>
    let PORT = 4040;
    let fileState = {
      $name: null,
      $size: null,
      $state: null,
      $port: null,
    };
    function fileChange() {
      updateFile().then(() => {
        setTimeout(() => {
          reflushFileList();
        }, 100);
      });
    }
    function updateFile() {
      return new Promise((resolve, reject) => {
        // setup file info
        const fileInfo = fileSelected();
        if (!fileInfo) {
          return null;
        }
        fileState.$name.text(fileInfo.name);
        fileState.$size.text(fileInfo.size);

        var fd = new FormData();
        fd.append("zipfile", fileInfo.file);
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener('load', () => {
          resolve();
        }, false);
        xhr.addEventListener('error', () => {
          reject(new Error('error'));
        }, false);
        xhr.addEventListener('abort', () => {
          reject('abort');
        }, false);
        xhr.open("POST", "/upload");
        xhr.send(fd);
      });
    }
    function uploadProgress(evt) {
      fileState.$state.removeClass('filestate-disable');
      if (evt.lengthComputable) {
        let percent = (evt.loaded * 100 / evt.total).toFixed(2);
        fileState.$state.css('width', `${percent}%`);
      } else {
        fileState.$state.addClass('filestate-disable');
      }
    }
    function fileSelected() {
      const file = document.getElementById('file').files[0];
      const fileInfo = {
        size: '',
        name: '',
        file,
      };
      if (!file) {
        return null;
      }
      var fileSize = 0;
      if (file.size > 1024 * 1024) {
        fileInfo.size = (file.size / (1024 * 1024)).toFixed(2) + ' MB';
      } else {
        fileInfo.size = (file.size / 1024).toFixed(2) + ' KB';
      }
      fileInfo.name = file.name;
      fileInfo.type = file.type;
      
      return fileInfo;
    }
    // 发送解压请求
    function exetract(el) {
      let $tr = $(el).closest('tr');
      let filename = $tr.attr('data-filename');
      let hasDir = $tr.attr('data-hasDir') === 'true';
      if (!hasDir || confirm('文件已解压过，是否覆盖？')) {
        fetch(`/extract/${filename}`).then(res => res.json()).then(result => {
          setTimeout(() => {
            reflushFileList();
          }, 100);
        });
      }
    }
    // 创建服务
    function createServer(el) {
      let $tr = $(el).closest('tr');
      let filename = $tr.attr('data-filename');
      if (confirm('是否在新端口上创建静态服务器')) {
        fetch(`/start/${filename}`).then(res => res.json())
          .then(result => {
            console.log('createServer >', result);
            setTimeout(() => {
              reflushFileList();
            }, 100);
          });
      }
    }

    // 发送删除请求
    function remove(el) {
      let $tr = $(el).closest('tr');
      let filename = $tr.attr('data-filename');
      if (confirm(`确定删除 '${filename}'（包括解压后的文件夹）吗？`)) {
        fetch(`/delete/${filename}`, {
          method: 'DELETE',
        }).then(res => res.json()).then(result => {
          setTimeout(() => {
            reflushFileList();
          }, 100);
        });
      }
    }
    function reflushFileList() {
      fetch('/files').then(res => res.json()).then(files => {
        const $table = $('#files');
        const $body = $table.find('tbody').empty();
        
        for (let i = 0; i < files.length; i++) {
          const file = files[i];
          const $tr = $('<tr></tr>')
            .attr('data-filename', file.name)
            .attr('data-hasDir', file.hasDir);
          const $name = $(`<td>${file.name}</td>`).appendTo($tr);
          const $date = $(`<td>${file.ctime}</td>`).appendTo($tr);
          const $hasDir = $(`<td></td>`).appendTo($tr);
          if (file.hasDir) {
            $hasDir.append($(`<a target="_blank" href="//${location.hostname}:${PORT}/${file.dirMeta.dirName}">/${file.dirMeta.dirName}</a>`))
          } else {
            $hasDir.append($('<span>未解压</span>'));
          }
          const $size = $(`<td>${file.size}</td>`).appendTo($tr);
          const $port = $(`<td>${file.port === -1 ? '无端口' : file.port}</td>`).appendTo($tr);
          
          const $handle = $('<td></td>').appendTo($tr)
            .append($('<button type="button" onclick="exetract(this)">解压到目录</button>'))
            .append($('<button type="button" onclick="remove(this)">删除</button>'));
          if (file.hasDir) {
            // 如果zip文件已被解压，则可以开启静态服务
            $handle.append($('<button type="button" onclick="createServer(this)">创建服务</button>'));
          }
          $body.append($tr);
        }
      });
    }
    $().ready(function() {
      const $fileState = $('#uploading-state');
      fileState.$name = $fileState.find('.filename');
      fileState.$size = $fileState.find('.filesize');
      fileState.$port = $fileState.find('.port');
      fileState.$state = $('.front');

      reflushFileList();
    });
    
  </script>
</body>
</html>